// =======================================================================
// 
//       Filename:  plugin.hpp
// 
//    Description:  
// 
//        Version:  1.0
//        Created:  27.03.2010 18:03:18
//       Revision:  none
//       Compiler:  g++
// 
//         Author:  Dominik 'domachine' Burgdörfer (-), dominik.burgdoerfer@googlemail.com
//        Company:  -
// 
// =======================================================================


#ifndef  PLUGIN_INC
#define  PLUGIN_INC
#include <iostream>
#include <stdexcept>
#include <map>
#include <vector>
#include <boost/filesystem.hpp>
#include <boost/any.hpp>
#include "pluginobject.hpp"

namespace webplodder {
    /**
     * @brief This class holds a Parser plugin
     */
    class Plugin {
        typedef std::map<std::string,std::string> PageMap;

    public:
        /**
         * The file is checked in the open method.
         * @brief Contructs a Plugin upon a shared object file.
         * @param[in] filename The file the Plugin points to
         */
        Plugin(const boost::filesystem::path& file);

        ~Plugin();

        /**
         * Invokes the dlopen function and the resolves the
         * `launch' symbol using the dlsym function.
         * @brief Opens the shared object.
         * @throw std::runtime_error Thrown if an error
         *                           occurs while opening
         *                           the shared object file
         *                           and reading resolving the
         *                           `launch' symbol
         */
        void open();

        /**
         * Invokes the the dlclose function on the shared object
         * handle.
         * @brief Closes the shared object.
         * @throw std:.runtime_error Thrown if an error occurs while
         *                           closing the handle
         */
        void close();

        /**
         * The name is the name of the file without
         * extension. It also represents the command name,
         * which invokes this Plugin.
         * @brief Returns the name of the Plugin.
         * @return The name of the Plugin
         */
        std::string name() const;

        /**
         * Invokes the `launch' symbol in the shared object file.
         * @brief Invokes the Plugin.
         * @param pagemap This variable map of the current Page.
         *                It can be modified by the Plugin.
         *                This manipulates the parsing process.
         * @param[out] oStream This is the std::ostream the Parser 
         *                     is currently writing on. The Plugin
         *                     should write its output to the stream.
         *                     It will be directly written to the
         *                     current file.
         */
        void call(PageMap& pagemap, 
                  std::ostream& oStream,
                  const std::vector<boost::any>& args);

    private:
        void* mhandle;
        PluginObject* mPluginObject;
        boost::filesystem::path mPath;
    };
}
#endif   // ----- #ifndef PLUGIN_INC  -----
